import 'dart:async';

String _data = '0';

///  Future(异步任务)    await async

void main() {
  // getData();
  // getData2();
  // getData3();
  // getData4();
  // getData5();

  getData6();
  print('做其它事情');
}

/**
 * ------非异步-------
 * 加不加async都是同步
 * 打印结果：
 *  开始data=0
    结束data=网络编程9999999
    做其它事情
 */
getData() async {
  print('开始data=$_data');
  for (int i = 0; i < 10000000; i++) {
    _data = '网络编程$i';
  }
  print('结束data=$_data');
}

/**
 * ------异步-------
 * 加不加async都是异步
 */
getData2() async {
  print('开始data=$_data');

  ///创建一个Future对象，这块代码是异步的
  Future(() {
    for (int i = 0; i < 10000000; i++) {
      _data = '网络编程$i';
    }
    print('结束data=$_data');
  });
}

/**
 * ------异步-------
 * TODO: await 和 async配合使用，
 * 只有async没有意义。（去掉await打印，结束data=网络编程0）
 * 结果：
 *  开始data=0
    做其它事情
    结束data=网络编程9999999
 */
getData3() async {
  print('开始data=$_data');

  ///创建一个Future对象，这块代码是异步的
  await Future(() {
    ///耗时操作
    ///1.后面操作必须是异步才能使用await修饰
    ///2.当前这个函数也必须是async修饰的函数
    for (int i = 0; i < 10000000; i++) {
      _data = '网络编程$i';
    }
  }); // ...任务。丢进异步任务里面去！
  print('结束data=$_data');
}

getData4() async {
  print('开始data=$_data');

  ///创建一个Future对象，这块代码是异步的
  Future future = Future(() {
    ///耗时操作
    ///1.后面操作必须是异步才能使用await修饰
    ///2.当前这个函数也必须是async修饰的函数
    for (int i = 0; i < 10000000; i++) {
      _data = '网络编程$i';
    }
  }).then((value) => print('结束data=$_data')); // ...任务。丢进异步任务里面去！

  print('再多干点事情！！！');
}

///--------------------------错误和状态-----------------------------------------------

/**
 *  开始data=0
    做其它事情
    结束value=xxxx
    再多干点事情！！！
 */
getData5() async {
  print('开始data=$_data');
  await Future(() {
    ///耗时操作
    ///1.后面操作必须是异步才能使用await修饰
    ///2.当前这个函数也必须是async修饰的函数
    for (int i = 0; i < 10000000; i++) {
      // _data = '网络编程$i';
    }
    return 'xxxx';
  }).then((value) => print('结束value=$value')); // ...任务。丢进异步任务里面去！(链式方式)

  print('再多干点事情！！！');
}

/**
 *  开始data=0
    做其它事情
    Unhandled exception:
    Exception: 网络异常！！！
    #0      getData6.<anonymous closure> (package:flutter_base_study/async/future_demo/future_demo.dart:121:5)
    #1      new Future.<anonymous closure> (dart:async/future.dart:256:37)
    #2      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
    #3      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
    #4      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
    #5      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)


    开始data=0
    再多干点事情！！！
    做其它事情
    使用的时候捕获到了：Exception: 网络异常！！！
    完成了
    完成的时候捕获异常Exception: 网络异常！！！

    TODO 最后catchError
 */
getData6() async {
  print('开始data=$_data');
  Future future = Future(() {
    ///耗时操作
    ///1.后面操作必须是异步才能使用await修饰
    ///2.当前这个函数也必须是async修饰的函数
    for (int i = 0; i < 10000000; i++) {
      // _data = '网络编程$i';
    }
    throw Exception('网络异常！！！');
    return 'xxxx';
  });

  ///链式调用大量代码可读性差
  future.then((value) => print('结束value=$value')).catchError(
      (e) => print('使用的时候捕获到了：' + e.toString())); // ...任务。丢进异步任务里面去！(链式方式)

  future
      .whenComplete(() => print('完成了'))
      .catchError((e) => print('完成的时候捕获异常' + e.toString()));

  // future.then(thenFunc);

  print('再多干点事情！！！');
}

/**   异步操作队列，队列是有序的
 * 链式调用，代码抽离
 */
getData7() async {
  print('开始data=$_data');
  Future(() {
    ///耗时操作
    ///1.后面操作必须是异步才能使用await修饰
    ///2.当前这个函数也必须是async修饰的函数
    for (int i = 0; i < 10000000; i++) {
      // _data = '网络编程$i';
    }
    throw Exception('网络异常！！！');
    return 'xxxx';
  })
      .then(thenFunc2) //方法抽出去，代码清晰
      .whenComplete(() => print('完成了'))
      .catchError(
          (e) => print('使用的时候捕获到了：' + e.toString())); // ...任务。丢进异步任务里面去！(链式方式)

  print('再多干点事情！！！');
}

/**
 * 队列
 */

FutureOr thenFunc(String value) {
  print('then进来了');
  print('结束value=$value');
}

///------------------多个异步处理------------------------

FutureOr thenFunc2(String value) {
  print('then进来了');
  print('结束value=$value');
}
